home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / ACKSRC.ZIP / ACKENG.C < prev    next >
Text File  |  1993-06-18  |  21KB  |  700 lines

  1. /****************  ACK-3D ( Animation Construction Kit 3D ) *******************/
  2. /* Engine Code          */
  3. /* Author: Lary Myers */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <mem.h>
  9. #include <alloc.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <string.h>
  14. #include <sys\stat.h>
  15. #include "ack3d.h"
  16. #include "ackext.h"
  17.  
  18. /****************************************************************************
  19. **                                       **
  20. ****************************************************************************/
  21. char xRay(int x,int y,int angle)
  22. {
  23.     char    Color;
  24.     int        i,j,mx,my;
  25.     int        TablePosn;
  26.     int        MapPosn,CurPosn;
  27.     int        xBeg;
  28.     long    xPos,xNext;
  29.     int        BitmapColumn;
  30.     int        xCenter,yCenter,xAdj;
  31.     int        ObjPosn;
  32.     int        oBegX,oBegY;
  33.     long    yPos;
  34.     long    yNext;
  35.     long    xd,yd,sy;
  36.     long    ObjDist;
  37.  
  38. xBeg  = x & 0xFFC0;        /* Get upper left corner of square    */
  39. yNext = yNextTable[angle];    /* PreCalc'd value of 64 * Tan(angle) */
  40.  
  41. if (angle > INT_ANGLE_270 || angle < INT_ANGLE_90)
  42.     {
  43.     xPos  = xBeg + GRID_SIZE;    /* Looking to the right */
  44.     xNext = GRID_SIZE;        /* Positive direction    */
  45.     }
  46. else
  47.     {
  48.     xPos  = xBeg;        /* Looking to the left    */
  49.     xNext = -GRID_SIZE;        /* Negative direction    */
  50.     yNext = -yNext;
  51.     }
  52.  
  53. /* Calculate the Y coordinate for the current square */
  54. yPos = (((long)xPos - (long)x) * LongTanTable[angle]) + ((long)y << FP_SHIFT);
  55.  
  56. while (1)
  57.     {
  58.     if (xPos < 0 || xPos > GRID_XMAX ||
  59.     yPos < 0 || yPos > GRID_YMAXLONG)
  60.     break;
  61.  
  62. /**************      Fixed point      Y/64 * 64    X / 64 ***********/
  63.     MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
  64.  
  65. /* First check for an object that has not been seen yet */
  66.     if ((Color = xObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
  67.     {
  68.     ObjFlags[Color] |= 1;            /* Indicate object has been seen */
  69.  
  70.     xd = ObjList[Color].x - x;
  71.     yd = ObjList[Color].y - y;
  72.     ObjDist = (xd * xd) + (yd * yd);    /* Calc relative distance */
  73.  
  74. /* Place the object in the array according to distance, with the ones closer */
  75. /* being drawn last. This will allow closer objects to hide farther objects  */
  76.  
  77.     j = TotalObjects;
  78.     for (i = 0; i < TotalObjects; i++)
  79.         {
  80.         if (ObjDist > ObjRelDist[i])
  81.         {
  82.  
  83.         for (j = TotalObjects; j > i; j--)
  84.             {
  85.             ObjRelDist[j] = ObjRelDist[j-1];
  86.             ObjNumber[j]  = ObjNumber[j-1];
  87.             ObjMapPosn[j] = ObjMapPosn[j-1];
  88.             }
  89.  
  90.         j = i;
  91.         i = TotalObjects;
  92.         }
  93.         }
  94.  
  95. /* Hold onto relavant data for the object found */
  96.     ObjNumber[j]  = Color;
  97.     ObjRelDist[j] = ObjDist;
  98.     ObjMapPosn[j] = MapPosn;
  99.     TotalObjects++;
  100.     ObjRelDist[TotalObjects] = 3200000;
  101.     }
  102.  
  103. /* Now check to see if a wall is being struck by the ray */
  104.     if ((Color = xGrid[MapPosn]) != 0)
  105.     {
  106.     xMapPosn = MapPosn;        /* Hold onto the map location */
  107.     iLastX     = xPos;
  108.     LastY1     = yPos;
  109.     if (Color == DOOR_XCODE)    /* Is this a door? */
  110.         {
  111.         yd = (yPos >> FP_SHIFT) & 0xFFC0;    /* Get the left side */
  112.         xd = yd + GRID_SIZE;        /* And the right side */
  113.         ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; /* Calc door distance */
  114.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  115.         {
  116.         xPos += xNext;            /* Nope, continue casting */
  117.         yPos += yNext;            /* the ray as before      */
  118.         continue;
  119.         }
  120.  
  121.         LastY1 = yPos + (yNext >> 1);    /* Adjust the X,Y values so   */
  122.         iLastX += (xNext >> 1);        /* the door is halfway in sq. */
  123.         }
  124.  
  125.     if (Color == DOOR_SECRETCODE)
  126.         {
  127.         if (xSecretColumn != 0)
  128.         {
  129.         sy = xSecretColumn * LongTanTable[angle];
  130.         ObjDist = (yPos + sy) >> FP_SHIFT;
  131.         yd = (yPos >> FP_SHIFT) & 0xFFC0;   /* Get the left side */
  132.         xd = yd + GRID_SIZE;            /* And the right side */
  133.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  134.             {
  135.             xPos += xNext;            /* Nope, continue casting */
  136.             yPos += yNext;            /* the ray as before      */
  137.             continue;
  138.             }
  139.         LastY1 = yPos + sy;
  140.         iLastX += xSecretColumn;
  141.         }
  142.         }
  143.  
  144.     return(Color);
  145.     }
  146.  
  147.     xPos += xNext;    /* Next X coordinate (fixed at 64 or -64)   */
  148.     yPos += yNext;    /* Next calculated Y coord for a delta of X */
  149.     }
  150.  
  151. return(0);        /* Return that no wall was found */
  152. }
  153.  
  154. /****************************************************************************
  155. **                                       **
  156. ****************************************************************************/
  157. char yRay(int x,int y,int angle)
  158. {
  159.     char    Color;
  160.     int        i,j,mx,my;
  161.     int        MapPosn;
  162.     int        yBeg;
  163.     long    yPos,yNext;
  164.     int        BitmapColumn;
  165.     int        xCenter,yCenter,yAdj;
  166.     int        ObjPosn;
  167.     int        oBegX;
  168.     long    xPos;
  169.     long    xNext;
  170.     long    xd,yd,ObjDist,sx;
  171.  
  172. yBeg  = y & 0xFFC0;        /* Same as div 64 then mul 64           */
  173. xNext = xNextTable[angle];    /* Pre-calc'd value of 64 / tan(angle) */
  174.  
  175. if (angle < INT_ANGLE_180)
  176.     {
  177.     yPos  = yBeg + GRID_SIZE;    /* Looking down          */
  178.     yNext = GRID_SIZE;        /* Positive direction */
  179.     }
  180. else
  181.     {
  182.     yPos  = yBeg;        /* Looking up          */
  183.     yNext = -GRID_SIZE;        /* Negative direction */
  184.     xNext = -xNext;
  185.     }
  186.  
  187. /* Calculate the X coordinate for the current square */
  188. xPos = (((long)yPos - (long)y) * LongInvTanTable[angle]) + ((long)x << FP_SHIFT);
  189.  
  190. oBegX = 0;
  191.  
  192. while (1)
  193.     {
  194.     if (xPos < 0 || xPos > GRID_XMAXLONG ||
  195.     yPos < 0 || yPos > GRID_YMAX)
  196.     break;
  197.  
  198. /***********   Y/64 * 64     Fixed point and /64 ******/
  199.     MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
  200.  
  201. /* Check for unseen objects first */
  202.     if ((Color = yObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
  203.     {
  204.     ObjFlags[Color] |= 2;        /* Signal object seen on Y cast */
  205.  
  206.     xd = ObjList[Color].x - x;
  207.     yd = ObjList[Color].y - y;
  208.     yd = (xd * xd) + (yd * yd);    /* Calc relative distance to object */
  209.  
  210. /* Place the object in the array according to distance, with the ones closer */
  211. /* being drawn last. This will allow closer objects to hide farther objects  */
  212.     j = TotalObjects;
  213.     for (i = 0; i < TotalObjects; i++)
  214.         {
  215.         if (yd > ObjRelDist[i])
  216.         {
  217.         for (j = TotalObjects; j > i; j--)
  218.             {
  219.             ObjRelDist[j] = ObjRelDist[j-1];
  220.             ObjNumber[j]  = ObjNumber[j-1];
  221.             ObjMapPosn[j] = ObjMapPosn[j-1];
  222.             }
  223.  
  224.         j = i;
  225.         i = TotalObjects;
  226.         }
  227.         }
  228.  
  229.     ObjNumber[j]  = Color;        /* Hold onto object data for later */
  230.     ObjRelDist[j] = yd;
  231.     ObjMapPosn[j] = MapPosn;
  232.     TotalObjects++;
  233.     ObjRelDist[TotalObjects] = 3200000;
  234.     }
  235.  
  236. /** Check for a wall being struck **/
  237.     if ((Color = yGrid[MapPosn]) != 0)
  238.     {
  239.     yMapPosn = MapPosn;        /* Hold onto map position */
  240.     LastX1     = xPos;
  241.     iLastY     = yPos;
  242.  
  243.     if (Color == DOOR_YCODE)    /* Is this a door? */
  244.         {
  245.         yd = (xPos >> FP_SHIFT) & 0xFFC0;    /* Calc top side of square   */
  246.         xd = yd + GRID_SIZE;        /* And bottom side of square */
  247.         ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
  248.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  249.         {
  250.         xPos += xNext;        /* No, continue on with ray cast */
  251.         yPos += yNext;
  252.         continue;
  253.         }
  254.  
  255.         LastX1 = xPos + (xNext >> 1);   /* Adjust coordinates so door is */
  256.         iLastY += (yNext >> 1);        /* Halfway into wall         */
  257.         }
  258.  
  259.     if (Color == DOOR_SECRETCODE)
  260.         {
  261.         if (ySecretColumn != 0)
  262.         {
  263.         sx = ySecretColumn * LongInvTanTable[angle];
  264.         ObjDist = (xPos + sx) >> FP_SHIFT;
  265.         yd = (xPos >> FP_SHIFT) & 0xFFC0;   /* Get the top side       */
  266.         xd = yd + GRID_SIZE;            /* And the bottom side */
  267.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  268.             {
  269.             xPos += xNext;            /* Nope, continue casting */
  270.             yPos += yNext;            /* the ray as before      */
  271.             continue;
  272.             }
  273.         LastX1 = xPos + sx;
  274.         iLastY += ySecretColumn;
  275.         }
  276.  
  277.         }
  278.  
  279.     return(Color);
  280.     }
  281.  
  282.     xPos += xNext;        /* Next calculated X value for delta Y */
  283.     yPos += yNext;        /* Next fixed value of 64 or -64       */
  284.  
  285.     if (++oBegX > 64)        /* Check a maximum number of squares   */
  286.     break;
  287.     }
  288.  
  289. return(0);        /* Return here if no Y wall is found */
  290. }
  291.  
  292.  
  293. /********************************************************